import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { history } from 'umi';

dayjs.extend(utc);

export function formatDataSize(val?: number) {
  if (!val) return '0B';
  let dataSize = isNaN(val!) ? 0 : val;
  let resp = '';
  if (val >= 1024 * 1024 * 1024 * 1024)
    resp =
      parseInt((dataSize / 1024 / 1024 / 1024 / 1024).toString(), 10) / 10 +
      'TB';
  else if (dataSize >= 1024 * 1204 * 1024)
    resp = parseInt((dataSize / 1024 / 1024 / 1024).toString(), 10) / 10 + 'GB';
  else if (dataSize >= 1024 * 1204)
    resp = parseInt((dataSize / 1024 / 1024).toString(), 10) / 10 + 'MB';
  else if (dataSize >= 1024)
    resp = parseInt((dataSize / 1024).toString(), 10) / 10 + 'KB';
  else resp = parseInt(dataSize.toString(), 10) + 'B';
  return resp;
}

export function formatDuration(val?: number) {
  if (!val) return '00:00:00';
  if (val < 0) val = 24 * 3600 + val;
  let h = parseInt((val / 3600).toString(), 10);
  let m = parseInt(((val % 3600) / 60).toString(), 10);
  let s = parseInt((val % 60).toString(), 10);
  let hText = h < 10 ? '0' + h : h;
  let mText = m < 10 ? '0' + m : m;
  let sText = s < 10 ? '0' + s : s;
  return hText + ':' + mText + ':' + sText;
}

export const formatUtcToLocal = (
  val?: string,
  outfmt = 'YYYY-MM-DD HH:mm:ss',
) => {
  if (!val || val == null || val === '' || val === '-') return '';

  return dayjs.utc(val, 'YYYY-MM-DD HH:mm:ss').local().format(outfmt);
};

export const formatDate = (
  val?: Date,
  outfmt = 'YYYY-MM-DD HH:mm:ss',
) => {
  if (!val || val == null) return '';

  return dayjs(val).format(outfmt);
};
export const formatRate = (rate: number | undefined, isByte: boolean) => {
  if (!rate) return '0B';
  if (isByte == false) {
    rate = rate / 8;
  }
  rate = rate / 1024;
  if (rate < 1024) {
    return rate.toFixed(1) + 'K';
  }
  rate = rate / 1024;
  if (rate < 1024) {
    return rate.toFixed(1) + 'M';
  }
  rate = rate / 1024;
  return rate.toFixed(1) + 'G';
};
export const formatRateBit = (rate: number | undefined, isByte?: boolean) => {
  if (!rate) return '0b';  
  if (isByte == true) {
    rate = rate * 8;
  }
  
  rate = rate / 1024;
  if (rate < 1024) {
    return rate.toFixed(1) + 'Kb';
  }
  rate = rate / 1024;
  if (rate < 1024) {
    return rate.toFixed(1) + 'Mb';
  }
  rate = rate / 1024;
  return rate.toFixed(1) + 'Gb';
};
export const formatRateMb = (rate: number | undefined, isByte: boolean) => {
  if (!rate) return 0;
  if (isByte == false) {
    rate = rate / 8;
  }
  rate = rate / 1024 / 1024;
  return Number(rate.toFixed(2));
};

export const formatPercentage = (
  rate: number | undefined,
  decimalPlaces: number,
) => {
  if (!rate) return 0;
  return (rate * 100).toFixed(decimalPlaces);
};

export const formatNumber = (num: number | string | undefined) => {
  return String(num ?? '').replace(/\B(?=(\d{4})+(?!\d))/g, ',');
};

export const listHtoV = (list: any[] | undefined, cols: number) => {
  if (!list) return [];
  let iCount = list.length;
  let iMod = iCount % cols;
  let iLine = Math.floor(iCount / cols);
  let iTime = iCount > cols ? cols : iCount;
  let arr: any[] = [];
  let iSrc = 0;
  for (let k = 0; k < iTime; k++) {
    for (let i = 0; i < iLine + (iMod > 0 ? 1 : 0); i++) {
      let iDest = k + i * cols;
      arr[iDest] = list[iSrc];
      iSrc++;
    }
    if (iMod > 0) iMod--;
  }
  return arr;
};

export const goUrl = (url: string, stateParams: any) => {
  history.push(url, { ...stateParams });
};

export const getStateValue = (stateName: string) => {
  let state = history.location.state;
  if (state) {
    for (let [itemName, itemValue] of Object.entries(state)) {
      // console.log(state,itemName,itemValue);
      if (itemName == stateName) {
        return itemValue;
      }
    }
  }
  return undefined;
};

export const dateAdd = (originDate:Date, interval:string, addNumber: number) => {
  switch (interval) {
      case 's': return new Date(originDate.getTime() + (1000 * addNumber));
      case 'n': return new Date(originDate.getTime() + (60000 * addNumber));
      case 'h': return new Date(originDate.getTime() + (3600000 * addNumber));
      case 'd': return new Date(originDate.getTime() + (86400000 * addNumber));
      case 'w': return new Date(originDate.getTime() + ((86400000 * 7) * addNumber));
      case 'q': return new Date(originDate.getFullYear(), (originDate.getMonth()) + addNumber * 3, originDate.getDate(), originDate.getHours(), originDate.getMinutes(), originDate.getSeconds());
      case 'm': return new Date(originDate.getFullYear(), (originDate.getMonth()) + addNumber, originDate.getDate(), originDate.getHours(), originDate.getMinutes(), originDate.getSeconds());
      case 'y': return new Date((originDate.getFullYear() + addNumber), originDate.getMonth(), originDate.getDate(), originDate.getHours(), originDate.getMinutes(), originDate.getSeconds());
  }
  return originDate;
}

export const seedRnd = (seed:number) => {
  seed = (seed * 9301 + 49297) % 233280;
  return seed / 233280.0;
}
export const getTextRanColor = (title:string) => {
  let seed = 0;
  for(let i=0; i<title.length; i++){
    seed += title.codePointAt(i);
  }
  seed = seed * 100;
  let color="#"+Math.floor(seedRnd(seed)*0xFFFFFF).toString(16).padStart(6,"0");
  return color;
}

export const getRanColor = () => {
  let color="#"+Math.floor(Math.random()*0xFFFFFF).toString(16).padStart(6,"0");
  return color;
}

export const getDayTextColor = (val: Date|undefined, hourInterval: number) => {
  if(!val) return '';

  const dateFormat = 'YYYY-MM-DD';
  let txtColor = 'orange';
  let date = dayjs(val);
  let dateText = date.format(dateFormat);
  let hour = date.hour() + hourInterval;

  let dateNow = dayjs(new Date());
  let today = dateNow.format(dateFormat);
  if(today == dateText){
    if (hour > dateNow.hour()) {
      txtColor = 'success';
    } 
    else if (hour == dateNow.hour()) {
      if (date.minute() >= dateNow.minute()) {
        txtColor = 'success';
      }
    }
    else{
      txtColor = 'cyan';
    }
  }

  // let timeText = date.format('HH:mm:ss');  
  // let yesterday = dateNow.add(-1, 'days').format(dateFormat);
  // let before_yesterday = dateNow.add(-2, 'days').format(dateFormat);

  return txtColor;
}



export const encode = (s:string) => {
  return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/([\\\.\*\[\]\(\)\$\^])/g, "\\$1");
}
export const decode = (s:string) => {
  return s.replace(/\\([\\\.\*\[\]\(\)\$\^])/g, "$1").replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&");
}
const replaceHighlight = (s:string, dest:any) => {
  var r = new RegExp(s, "g");
  var tm = null;
  var t = dest.nodeValue;
  var cnt = 0;
  if(tm = t.match(r)) {
    cnt = tm.length;
    t = t.replace(r, "{searchHL}" + decode(s) + "{/searchHL}")
    dest.nodeValue = t;
  }
  return cnt;
}
const loopSearchHighlight = (s:string, obj:any) => {
  var cnt = 0;
  if(obj.nodeType == 3) {
    cnt = replaceHighlight(s, obj);
    return cnt;
  }
  for(var i = 0, c; c = obj.childNodes[i]; i++) {
    if(!c.className || c.className != "highlight") {
      cnt += loopSearchHighlight(s, c);
    }
  }
  return cnt;
}
export const highlight = (html:string, keyWords:string|undefined) =>{
  if(!keyWords || keyWords.length == 0) return html;
  if(html.length == 0) {
    return html;
  }
  var obj = document.createElement("div");
  obj.innerHTML = html;
  var s = encode(keyWords);
  var t = obj.innerHTML.replace(/<span\s+class=.?highlight.?>([^<>]*)<\/span>/gi, "$1");
  obj.innerHTML = t;
  var cnt = loopSearchHighlight(s, obj);
  t = obj.innerHTML
  var r = /{searchHL}(({(?!\/searchHL})|[^{])*){\/searchHL}/g
  t = t.replace(r, "<span style='color:red;background-color:yellow'>$1</span>");
  return t;
}

